package com.jwgf.Half485.fxthreadpool;

import android.util.Log;

import java.util.Arrays;
import java.util.Locale;

public class FxUtils {
    public static char STX = 0x02;
    public static char ETX = 0x03;
    public static char ENQ = 0x05;
    public static char ACK = 0x06;
    public static String PC = "FF";
    public static String WR = "WR";
    public static String WW = "WW";
    public static String TIMEOUT = "A";

    public static byte[] createWRCmd(int id, int addr, int len) {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%02x", id));
        sb.append(PC);
        sb.append(WR);
        sb.append(TIMEOUT);
        sb.append("D");
        sb.append(String.format("%04d", addr));
        sb.append(String.format("%02x", len).toUpperCase(Locale.getDefault()));
        sb.append(sum(sb.toString()));
        sb.insert(0, ENQ);
        return sb.toString().getBytes();
    }

    public static byte[] createWWMultiCmd(int id, int addr, short[] data) {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%02x", id));
        sb.append(PC);
        sb.append(WW);
        sb.append(TIMEOUT);
        sb.append("D");
        sb.append(String.format("%04d", addr));
        short len = (short) data.length;
        sb.append(String.format("%02x", len).toUpperCase(Locale.getDefault()));
        for (short element : data) {
            sb.append(String.format("%04x", element).toUpperCase(Locale.getDefault()));
        }
        sb.append(sum(sb.toString()));
        sb.insert(0, ENQ);
        return sb.toString().getBytes();
    }

    public static byte[] createWWCmd(int id, int addr, short data) {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%02d", id));
        sb.append(PC);
        sb.append(WW);
        sb.append(TIMEOUT);
        sb.append("D");
        sb.append(String.format("%04d", addr));
        sb.append(String.format("%02x", 1).toUpperCase(Locale.getDefault()));

        sb.append(String.format("%04x", data).toUpperCase(Locale.getDefault()));
        sb.append(sum(sb.toString()));
        sb.insert(0, ENQ);
        return sb.toString().getBytes();
    }

    public static String getRequestCommand(byte[] requestData) {
        StringBuilder sb = new StringBuilder();
        sb.append((char) requestData[5]);
        sb.append((char) requestData[6]);
        return sb.toString();
    }

    public static int[] getRequestData(byte[] requestData) {
        int dataLength = Integer.parseInt(new String(new byte[]{requestData[13], requestData[14]}));
        byte[] requestStr = new byte[dataLength * 4];
        System.arraycopy(requestData, 15, requestStr, 0, requestStr.length);

        int[] requestInt = new int[dataLength];
        for (int i = 0; i < dataLength; ++i) {
            byte[] temp = new byte[4];
            System.arraycopy(requestStr, i * 4, temp, 0, temp.length);
            requestInt[i] = Integer.parseInt(new String(temp), 16);
        }

        return requestInt;
    }

    public static int getRequestComponentAmount(byte[] requestData) {
        byte[] temp = new byte[2];
        System.arraycopy(requestData, 13, temp, 0, 2);
        String lenStr = new String(temp);
        try {
            int len = Integer.parseInt(lenStr, 16);
            return len;
        } catch (NumberFormatException e) {
            Log.i("parseInt", Arrays.toString(requestData));
        }
        return 0;
    }

    public static boolean getReturnCheckResult(byte[] returnData) {
        StringBuilder sb = new StringBuilder();
        int len = returnData.length;
        for (int i = 1; i < len; i++) {
            sb.append(returnData[i]);
        }
        String localCheckedSum = sum(sb.toString());
        StringBuilder sb2 = new StringBuilder();
        sb2.append(returnData[len - 2]);
        sb2.append(returnData[len - 1]);
        String targetCheckSum = sb.toString();
        if (localCheckedSum.equalsIgnoreCase(targetCheckSum)) {
            return true;
        } else {
            return false;
        }
    }

    public static char getRequestComponentType(byte[] requestData) {
        return (char) requestData[8];
    }

    public static int getRequestAddr(byte[] requestData) {
        byte[] temp = new byte[4];
        System.arraycopy(requestData, 9, temp, 0, 4);
        String addrStr = new String(temp);
        return Integer.parseInt(addrStr, 10);
    }

    public static int[] getReturnData(byte[] retData) {
        byte[] rawData = new byte[retData.length - 8];
        System.arraycopy(retData, 5, rawData, 0, rawData.length);
        int[] tempData = new int[rawData.length / 4];
        for (int i = 0; i < rawData.length; i += 4) {
            byte[] strData = new byte[4];
            System.arraycopy(rawData, i, strData, 0, 4);
            String str = new String(strData);
            tempData[i / 4] = Integer.parseInt(str, 16);
        }
        return tempData;
    }

    public static int getRequestId(byte[] request) {
        byte[] temp = new byte[2];
        System.arraycopy(request, 1, temp, 0, 2);
        String idStr = new String(temp);
        int id = Integer.parseInt(idStr);
        return id;
    }

    public static int getReturnId(byte[] request) {
        byte[] temp = new byte[2];
        System.arraycopy(request, 1, temp, 0, 2);
        String idStr = new String(temp);
        int id = Integer.parseInt(idStr);
        return id;
    }

    public static int getkey(int plcId, int addr) {
        return (plcId << 16) | addr;
    }

    public static int generateFaultKey(int id, int addr, int faultBit) {
        return (id << 24) | (addr << 8) | faultBit;
    }

    public static String sum(String cmd) {
        byte[] data = cmd.getBytes();
        int sum = 0;
        for (byte b : data) {
            sum += b;
        }
        return String.format("%02x", sum & 0xff).toUpperCase(Locale.getDefault());
    }

    public static int getReturnByteLen(byte[] requestData) {
        byte[] temp = new byte[2];
        System.arraycopy(requestData, 13, temp, 0, 2);
        String lenStr = new String(temp);
        try {
            int len = Integer.parseInt(lenStr, 16);
            return len * 4 + 8;
        } catch (NumberFormatException e) {
            Log.i("parseInt", Arrays.toString(requestData));
        }
        return 0;
    }

    // 读校验
    public static boolean sumCheck(byte[] recv) {
        String res = new String(recv);
        res = res.substring(1);
        String sum = res.substring(res.length() - 2, res.length());
        String sumCalc = FxUtils.sum(res.substring(0, res.length() - 2));
        if (sum.equals(sumCalc)) {
            return true;
        } else {
            return false;
        }
    }

    //写校验
    public static boolean writeACK(byte[] send, byte[] recv) {
        String request = new String(send);
        String res = new String(recv);
        String requestId = request.substring(1, 3);
        String ACK = new StringBuilder().append(FxUtils.ACK).append(requestId).append("FF").toString();
        if (ACK.equals(res)) {
            return true;
        } else {
            return false;
        }
    }

    public static String checkCmdType(byte[] send) {
        String request = new String(send);
        return request.substring(5, 7);
    }


}
